home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
database
/
packftp.zip
/
PACKFTP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-22
|
6KB
|
289 lines
/* Program: packftp
* Author: Mark R. Rinfret (mrr@mrsoft.network23.com)
* Date: 11/28/94
*
* Usage: packftp <input_file> <output_file>
*
* Purpose:
* This program converts the FTP Site List, currently maintained
* by Perry Rovers (Perry.Rovers@kub.nl), into a file of records
* containing quote-delimited, comma-separated values. The resulting
* file is suitable for importing into a database of your choice,
* though I created (and distributed with this program) a Microsoft
* Access 2.0 database which works quite nicely.
*
* This program is contributed to the public domain and the author
* surrenders all rights to it. Please feel free to enhance it,
* redistribute it, serve it with cream cheese, whatever. There's
* certainly plenty of room for improvement. Note that there is
* currently no error checking for values whose lengths exceed
* VALUE_SIZE.
*
* Instructions:
* prepare the <input_file> by concatenating the various pieces of
* the FTP Site List into one file. Remove all mail headers and
* other 'noise'. A blank line between site definitions is OK.
* No other alterations should be necessary and, other than the
* Site entry (which must appear first), the order of the entries
* could actually change without upsetting this program.
*
* Next, run the packftp program. Example:
*
* packftp ftp.raw ftp.imp
*
* You can then import the resulting file into an appropriately
* designed database.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 255
#define VALUE_SIZE 4096
#define startFlag "BEGIN_FTP_LIST" /* Added by list preparer. */
#define FIELD_COUNT 13
static char *titles[FIELD_COUNT] = {
"Site",
"Country",
"GMT",
"Date",
"Source",
"Alias",
"Admin",
"Organ",
"Server",
"System",
"URL",
"Comment",
"Files",
};
static char *fields[FIELD_COUNT];
static int maxLengths[FIELD_COUNT];
static char buffer[BUFFER_SIZE];
FILE *inFile = NULL;
FILE *outFile = NULL;
int recordCount = 0;
int lineNumber = 0;
int
FillBuffer(void)
{
int length = 0;
while (! feof(inFile) && length == 0)
{
if (fgets(buffer, BUFFER_SIZE, inFile))
{
++lineNumber;
length = strlen(buffer);
if (length)
{
buffer[--length] = '\0'; /* Drop the newline */
}
}
}
return length;
}
void
PutFields(int doTitles)
{
int i;
int length;
char *p;
char *v;
for (i = 0; i < FIELD_COUNT; ++i)
{
/* Replace all double quotes with single quotes. */
v = (doTitles ? titles[i] : fields[i]);
if (! doTitles)
{
for (p = v; *p; ++p)
if (*p == '"') *p = '\'';
length = strlen(v); /* Gather statistics. */
if (length > maxLengths[i])
maxLengths[i] = length;
}
fprintf(outFile,"\"%s\",", v);
if (! doTitles)
*v = '\0'; /* Mark it used. */
}
fprintf(outFile, "*EOR*\n"); /* Output end-of-record. */
}
void
ProcessKeywords(void)
{
int i;
char *kw;
int kwx = -1;
char *value = NULL;
PutFields(1);
while (! feof(inFile) )
{
if (! *buffer)
{
FillBuffer();
}
/* See if column 7 contains a keyword. */
if (buffer[7] == ':')
kw = strtok(buffer, " :");
else
kw = NULL;
if (! kw )
{
/* Multi-line field value? */
if (value)
{
/* Separate the lines of multi-line entries with a space. */
if (*value) strcat(value, " ");
strcat(value, buffer+9);
}
*buffer = '\0';
}
else
{
/* Recognize keyword? */
for (i = 0, kwx = -1; i < FIELD_COUNT; ++i)
{
/* Do a case-insensitive compare. I found one instance
* where this was necessary (SItes vs. Sites).
*/
if (strcmpi(buffer, titles[i]) == 0)
{
kwx = i;
break;
}
}
if (kwx == -1)
{
printf("*** Unrecognized keyword at line %d: '%s'\n",
lineNumber, buffer);
value = NULL;
}
else
{
value = fields[kwx];
}
*buffer = '\0'; /* Don't re-scan this buffer. */
if (kwx == 0) /* First field? */
{
/* Flush the previous record? */
if (recordCount)
{
PutFields(0);
}
++recordCount;
}
/* Save the value? */
if (value) strcat(value, buffer+9);
}
} /* ! feof(inFile) */
if (*fields[0])
PutFields(0);
}
/* We enter ProcessList with startFlag in the buffer. */
void
ProcessList(void)
{
int i;
/* This loop should only execute once since ProcessKeywords
* doesn't give up control until the whole file has been read.
*/
while (! feof(inFile))
{
if (FillBuffer())
{
if (buffer[7] == ':') ProcessKeywords();
}
}
puts("\nMaximum field lengths:");
for (i = 0; i < FIELD_COUNT; ++i)
{
printf("\t%-12s: %d\n", titles[i], maxLengths[i]);
}
}
int
main(int argc, char **argv)
{
int gotStart = 0;
int i;
if (argc != 3)
{
puts("usage: pack_ftp_list <infile> <outfile>");
exit(1);
}
for (i = 0; i < FIELD_COUNT; ++i)
{
if (! (fields[i] = calloc(1,VALUE_SIZE)) )
{
puts("*** Out of memory! ***");
exit(1);
}
}
inFile = fopen(argv[1], "r");
if (! inFile)
{
perror(argv[1]);
exit(1);
}
outFile = fopen(argv[2], "w");
if (! outFile)
{
perror(argv[2]);
exit(1);
}
while (! feof(inFile) )
{
if (FillBuffer())
{
if (strcmp(buffer, startFlag) == 0)
{
gotStart = 1;
ProcessList();
}
}
}
if (! gotStart)
{
printf("*** Never found '%s' string.\n", startFlag);
exit(1);
}
if (inFile) fclose(inFile);
if (outFile) fclose(outFile);
return 0;
}